home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / cpp_libs / awe2-0_1.lha / awe2-0.1 / Src / HardwareContext-m68k.cc < prev    next >
C/C++ Source or Header  |  1990-07-09  |  5KB  |  179 lines

  1. // This may look like C code, but it is really -*- C++ -*-
  2. // 
  3. // Copyright (C) 1988 University of Illinois, Urbana, Illinois
  4. // Copyright (C) 1989 University of Colorado, Boulder, Colorado
  5. // Copyright (C) 1990 University of Colorado, Boulder, Colorado
  6. //
  7. // written by Dirk Grunwald (grunwald@foobar.colorado.edu)
  8. //
  9. #include "HardwareContext.h"
  10. #include "CpuMultiplexor.h"
  11. #include "Thread.h"
  12. #include "assert.h"
  13. #include <stream.h>
  14.  
  15. //
  16. //    Many machines have the same (or very similar) stack format.
  17. //    The 68K & 32K are examples of such machines.
  18. //
  19. //    The const *registers* defines the number of additional longwords
  20. //    needed on the stack past the last frame pointer. This value needs
  21. //    to jibe with the one in HardwareContext-<arch>.s.
  22. //
  23.  
  24.  
  25. const long MagicStackMarker = 0x464f4f20;    // this says 'FOO '
  26.  
  27.  
  28. //
  29. //    checkBytesSaved won't include a6 and a7, so it thinks
  30. //    only 10 registers (6 data, 4 address) are saved.
  31. //
  32. static const int expectedBytesSavedInContext
  33.     = 4 * 10
  34.     + 4 * HardwareContextFloatQuads;
  35. static int numberOfBytesSavedInContext = 0;
  36. static void computeBytesSaved();
  37.  
  38. HardwareContext::HardwareContext (int check, unsigned size)
  39. {
  40.     checkStackLimits = check;
  41.  
  42.     stackBase = 0;
  43.     stackEnd = 0;
  44.     stackMax = 0;
  45.     stackSize = 0;
  46.     stackCheck = 0;
  47.     stackMallocAt = 0;
  48.  
  49.     if (size > 0) {
  50.     stackSize = size;
  51.     stackMallocAt = new void *[ stackSize ];
  52.     //
  53.     // stackBase should point to the first writeable cell of the
  54.     // new stack.
  55.     //
  56.     stackEnd = stackMallocAt;
  57.     stackBase = &stackMallocAt[stackSize-1];
  58.     }
  59.     else {
  60.     //
  61.     // Have the main process figure out how many registers
  62.     // (actually, Quads) are pushed when we save an entire context.
  63.     // Do this by calling magicSwitchTo with itself. This has
  64.     // the side-effect of storing fp & sp in the context.
  65.     //
  66.  
  67.     magicSwitchTo(this);
  68.     numberOfBytesSavedInContext = (long) fp - (long) sp;
  69.  
  70.     assert( numberOfBytesSavedInContext == expectedBytesSavedInContext );
  71.     }
  72. }
  73.  
  74. HardwareContext::reclaimStack()
  75. {
  76.     if ( stackMallocAt ) {
  77.     if ( check ) {
  78.         mprotect(stackMallocAt, pageSizeInBytes, PROT_READ | PROT_WRITE);
  79.     }
  80.     free(stackMallocAt);
  81.     stackMallocAt = 0;
  82.     }
  83. }
  84.  
  85. void
  86. HardwareContext::magicSwitchTo(HardwareContext *to)
  87. {
  88.     //
  89.     //    UNTESTED
  90.     //
  91.     asm( " " : : :
  92.     "d1", "d2", "d3", "d4", "d5", "d6", "d7",
  93.     "a0", "a1", "a2", "a3", "a4", "a5", "a6", "sp",
  94.     "fp0", "fp1", "fp2", "fp3", "fp4", "fp5", "fp6", "fp7");
  95.  
  96.     asm("movl    a7,%0" : "=g" (sp));
  97.     asm("movl    a6,%0" : "=g" (fp));
  98.     asm("movl    %0,a7" : : "g" (to -> sp));
  99.     asm("movl    %0,a6" : : "g" (to -> fp));
  100. }
  101.  
  102. void
  103. HardwareContext::stackOverflow()
  104. {
  105.     register unsigned depth = stackBase - getSp();
  106.     if (stackMax < depth) {
  107.     stackMax = depth;
  108.     }
  109.     if ( stackMax >= stackSize ) {
  110.     cerr << "\nStack overflow\n";
  111.     cerr << " getSp() = " << hex(long(getSp()));
  112.     cerr << " and stackBase = " << hex(long(stackBase)) << "\n";
  113.     cerr << *this << "\n";
  114.     cerr << "Current task is \n";
  115.     cerr << *(CurrentThread());
  116.     cerr << "\n";
  117.     cerr.flush();
  118.     }
  119.     assert( stackMax < stackSize );
  120.     assert( *stackCheck == MagicStackMarker );
  121. }
  122.  
  123.  
  124. void
  125. HardwareContext::buildReturnFrame(void *returnThis, voidFuncP returnAddress)
  126. {
  127.     //
  128.     //    To build a thread, we return to the first address of startOff,
  129.     //    which will use the current FP & SP to build a local context,
  130.     //    and then call the user main.
  131.     //
  132.     //    startOff needs to have a valid frame. The return address for this
  133.     //    frame is NULL, since we never exit procedure startOff.
  134.     //
  135.     
  136.     stackCheck = (long *) stackBase;
  137.     HardwareContextQuad **stack = (HardwareContextQuad **) stackBase;
  138.     *(stack--) = (HardwareContextQuad *) MagicStackMarker;
  139.     *(stack--) = 0;            // return address
  140.     HardwareContextQuad **startOffFp = stack;
  141.     *(stack--) = 0;            // frame pointer
  142.     
  143.     //
  144.     //    Construct the stack frame that will be used in procedure startOff.
  145.     //    startOff needs to know the value for *this*, which is passed in
  146.     //    as the first parameter. It also gets the back-link FP for the
  147.     //    last frame (build above).
  148.     //
  149.     
  150.     *(stack--) = (HardwareContextQuad *) returnThis;
  151.     HardwareContextQuad **nullFp = stack;
  152.     
  153.     // FP for previous frame
  154.     
  155.     *(stack--) = (HardwareContextQuad *) startOffFp;
  156.     //
  157.     //    Now build the stack frame that is used to return to startOff
  158.     //
  159.     
  160.     *(stack--) = (HardwareContextQuad *) returnAddress;
  161.     
  162.     a6 = (HardwareContextQuad) stack;
  163.     
  164.     *(stack) = (HardwareContextQuad *) nullFp;
  165.     a7 = (HardwareContextQuad) stack;
  166. }
  167.  
  168. void
  169. HardwareContext::classPrintOn(ostream& s)
  170. {
  171.     s << "[HardwareContext] Stack spans " << hex(long(stackEnd));
  172.     s << " to " << hex(long(stackBase));
  173.     s << " used is  " << (stackMax) << " of " << stackSize << "\n";
  174.     s << "[HardwareContext] fp = " << hex(long(a6));
  175.     s << " sp = " << hex(long(a7));
  176.     long p = *( (long *) a6 );
  177.     s << " @fp = " << hex(p) << "\n";
  178. }
  179.